home *** CD-ROM | disk | FTP | other *** search
/ Turnbull China Bikeride / Turnbull China Bikeride - Disc 2.iso / STUTTGART / TEMP / GNU / flex / C < prev    next >
Text File  |  1995-06-28  |  8KB  |  254 lines

  1. C++
  2. Previous: <Performance=>Performanc> * Next: <Incompatibilities=>Incompatib> * Up: <Top=>!Root>
  3.  
  4. #Wrap on
  5. {fH3}Generating C++ scanners{f}
  6.  
  7. {fCode}flex{f} provides two different ways to generate scanners for
  8. use with C++.  The first way is to simply compile a
  9. scanner generated by {fCode}flex{f} using a C++ compiler instead of a C
  10. compiler.  You should not encounter any compilations
  11. errors (please report any you find to the email address
  12. given in the Author section below).  You can then use C++
  13. code in your rule actions instead of C code.  Note that
  14. the default input source for your scanner remains {fCode}yyin{f},
  15. and default echoing is still done to {fCode}yyout{f}.  Both of these
  16. remain {fEmphasis}FILE \*{f} variables and not C++ {fCode}streams{f}.
  17.  
  18. You can also use {fCode}flex{f} to generate a C++ scanner class, using
  19. the {fEmphasis}-+{f} option, (or, equivalently, {fEmphasis}%option c++{f}), which
  20. is automatically specified if the name of the flex executable ends
  21. in a {fEmphasis}+{f}, such as {fCode}flex++{f}.  When using this option, flex
  22. defaults to generating the scanner to the file {fCite}lex.yy.cc{f} instead
  23. of {fCite}lex.yy.c{f}.  The generated scanner includes the header file
  24. {fCite}FlexLexer.h{f}, which defines the interface to two C++ classes.
  25.  
  26. The first class, {fCode}FlexLexer{f}, provides an abstract base
  27. class defining the general scanner class interface.  It
  28. provides the following member functions:
  29.  
  30. #Indent +4
  31. #Indent
  32. {fEmphasis}const char\* YYText(){f}
  33. #Indent +4
  34. returns the text of the most recently matched
  35. token, the equivalent of {fCode}yytext{f}.
  36.  
  37. #Indent
  38. {fEmphasis}int YYLeng(){f}
  39. #Indent +4
  40. returns the length of the most recently matched
  41. token, the equivalent of {fCode}yyleng{f}.
  42.  
  43. #Indent
  44. {fEmphasis}int lineno() const{f}
  45. #Indent +4
  46. returns the current input line number (see {fEmphasis}%option yylineno{f}),
  47. or 1 if {fEmphasis}%option yylineno{f} was not used.
  48.  
  49. #Indent
  50. {fEmphasis}void set\_debug( int flag ){f}
  51. #Indent +4
  52. sets the debugging flag for the scanner, equivalent to assigning to
  53. {fCode}yy\_flex\_debug{f} (see the Options section above).  Note that you
  54. must build the scanner using {fEmphasis}%option debug{f} to include debugging
  55. information in it.
  56.  
  57. #Indent
  58. {fEmphasis}int debug() const{f}
  59. #Indent +4
  60. returns the current setting of the debugging flag.
  61.  
  62. #Indent
  63.  
  64. Also provided are member functions equivalent to
  65. {fEmphasis}yy\_switch\_to\_buffer(), yy\_create\_buffer(){f} (though the
  66. first argument is an {fEmphasis}istream\*{f} object pointer and not a
  67. {fEmphasis}FILE\*{f}, {fEmphasis}yy\_flush\_buffer(){f}, {fEmphasis}yy\_delete\_buffer(){f},
  68. and {fEmphasis}yyrestart(){f} (again, the first argument is a {fEmphasis}istream\*{f}
  69. object pointer).
  70.  
  71. The second class defined in {fCite}FlexLexer.h{f} is {fCode}yyFlexLexer{f},
  72. which is derived from {fCode}FlexLexer{f}.  It defines the following
  73. additional member functions:
  74.  
  75. #Indent +4
  76. #Indent
  77. {fEmphasis}yyFlexLexer( istream\* arg\_yyin = 0, ostream\* arg\_yyout = 0 ){f}
  78. #Indent +4
  79. constructs a {fCode}yyFlexLexer{f} object using the given
  80. streams for input and output.  If not specified,
  81. the streams default to {fCode}cin{f} and {fCode}cout{f}, respectively.
  82.  
  83. #Indent
  84. {fEmphasis}virtual int yylex(){f}
  85. #Indent +4
  86. performs the same role is {fEmphasis}yylex(){f} does for ordinary
  87. flex scanners: it scans the input stream, consuming
  88. tokens, until a rule's action returns a value.  If you derive a subclass
  89. {fStrong}S{f}
  90. from {fCode}yyFlexLexer{f}
  91. and want to access the member functions and variables of
  92. {fStrong}S{f}
  93. inside {fEmphasis}yylex(){f},
  94. then you need to use {fEmphasis}%option yyclass="{fStrong}S{f}"{f}
  95. to inform {fCode}flex{f}
  96. that you will be using that subclass instead of {fCode}yyFlexLexer{f}.
  97. In this case, rather than generating {fEmphasis}yyFlexLexer::yylex(){f},
  98. {fCode}flex{f} generates {fEmphasis}{fStrong}S{f}::yylex(){f}
  99. (and also generates a dummy {fEmphasis}yyFlexLexer::yylex(){f}
  100. that calls {fEmphasis}yyFlexLexer::LexerError(){f}
  101. if called).
  102.  
  103. #Indent
  104. {fEmphasis}virtual void switch\_streams(istream\* new\_in = 0, ostream\* new\_out = 0){f}
  105. #Indent +4
  106. reassigns {fCode}yyin{f} to {fCode}new\_in{f}
  107. (if non-nil)
  108. and {fCode}yyout{f} to {fCode}new\_out{f}
  109. (ditto), deleting the previous input buffer if {fCode}yyin{f}
  110. is reassigned.
  111.  
  112. #Indent
  113. {fEmphasis}int yylex( istream\* new\_in = 0, ostream\* new\_out = 0 ){f}
  114. #Indent +4
  115. first switches the input streams via {fEmphasis}switch\_streams( new\_in, new\_out ){f}
  116. and then returns the value of {fEmphasis}yylex(){f}.
  117.  
  118. #Indent
  119.  
  120. In addition, {fCode}yyFlexLexer{f} defines the following protected
  121. virtual functions which you can redefine in derived
  122. classes to tailor the scanner:
  123.  
  124. #Indent +4
  125. #Indent
  126. {fEmphasis}virtual int LexerInput( char\* buf, int max\_size ){f}
  127. #Indent +4
  128. reads up to {fEmphasis}max\_size{f} characters into {fStrong}buf{f} and
  129. returns the number of characters read.  To indicate
  130. end-of-input, return 0 characters.  Note that
  131. "interactive" scanners (see the {fEmphasis}-B{f} and {fEmphasis}-I{f} flags)
  132. define the macro {fCode}YY\_INTERACTIVE{f}.  If you redefine
  133. {fCode}LexerInput(){f} and need to take different actions
  134. depending on whether or not the scanner might be
  135. scanning an interactive input source, you can test
  136. for the presence of this name via {fEmphasis}\#ifdef{f}.
  137.  
  138. #Indent
  139. {fEmphasis}virtual void LexerOutput( const char\* buf, int size ){f}
  140. #Indent +4
  141. writes out {fStrong}size{f} characters from the buffer {fStrong}buf{f},
  142. which, while NUL-terminated, may also contain
  143. "internal" NUL's if the scanner's rules can match
  144. text with NUL's in them.
  145.  
  146. #Indent
  147. {fEmphasis}virtual void LexerError( const char\* msg ){f}
  148. #Indent +4
  149. reports a fatal error message.  The default version
  150. of this function writes the message to the stream
  151. {fCode}cerr{f} and exits.
  152.  
  153. #Indent
  154.  
  155. Note that a {fCode}yyFlexLexer{f} object contains its {fEmphasis}entire{f}
  156. scanning state.  Thus you can use such objects to create
  157. reentrant scanners.  You can instantiate multiple instances of
  158. the same {fCode}yyFlexLexer{f} class, and you can also combine
  159. multiple C++ scanner classes together in the same program
  160. using the {fEmphasis}-P{f} option discussed above.
  161. Finally, note that the {fEmphasis}%array{f} feature is not available to
  162. C++ scanner classes; you must use {fEmphasis}%pointer{f} (the default).
  163.  
  164. Here is an example of a simple C++ scanner:
  165.  
  166. #Wrap off
  167. #fCode
  168.     \/\/ An example of using the flex C++ scanner class.
  169.  
  170. %\{
  171. int mylineno = 0;
  172. %\}
  173.  
  174. string  \\"[^\\n"]+\\"
  175.  
  176. ws      [ \\t]+
  177.  
  178. alpha   [A-Za-z]
  179. dig     [0-9]
  180. name    (\{alpha\}|\{dig\}|\\$)(\{alpha\}|\{dig\}|[\_.\\-\/$])\*
  181. num1    [-+]?\{dig\}+\\.?([eE][-+]?\{dig\}+)?
  182. num2    [-+]?\{dig\}\*\\.\{dig\}+([eE][-+]?\{dig\}+)?
  183. number  \{num1\}|\{num2\}
  184.  
  185. %%
  186.  
  187. \{ws\}    \/\* skip blanks and tabs \*\/
  188.  
  189. "\/\*"    \{
  190.         int c;
  191.  
  192.         while((c = yyinput()) != 0)
  193.             \{
  194.             if(c == '\\n')
  195.                 ++mylineno;
  196.  
  197.             else if(c == '\*')
  198.                 \{
  199.                 if((c = yyinput()) == '\/')
  200.                     break;
  201.                 else
  202.                     unput(c);
  203.                 \}
  204.             \}
  205.         \}
  206.  
  207. \{number\}  cout << "number " << YYText() << '\\n';
  208.  
  209. \\n        mylineno++;
  210.  
  211. \{name\}    cout << "name " << YYText() << '\\n';
  212.  
  213. \{string\}  cout << "string " << YYText() << '\\n';
  214.  
  215. %%
  216.  
  217. Version 2.5               December 1994                        44
  218.  
  219. int main( int \/\* argc \*\/, char\*\* \/\* argv \*\/ )
  220.     \{
  221.     FlexLexer\* lexer = new yyFlexLexer;
  222.     while(lexer->yylex() != 0)
  223.         ;
  224.     return 0;
  225.     \}
  226. #f
  227. #Wrap on
  228.  
  229. If you want to create multiple (different) lexer classes,
  230. you use the {fEmphasis}-P{f} flag (or the {fEmphasis}prefix={f} option) to rename each
  231. {fCode}yyFlexLexer{f} to some other {fCode}xxFlexLexer{f}.  You then can
  232. include {fEmphasis}<FlexLexer.h>{f} in your other sources once per lexer
  233. class, first renaming {fCode}yyFlexLexer{f} as follows:
  234.  
  235. #Wrap off
  236. #fCode
  237. \#undef yyFlexLexer
  238. \#define yyFlexLexer xxFlexLexer
  239. \#include <FlexLexer.h>
  240.  
  241. \#undef yyFlexLexer
  242. \#define yyFlexLexer zzFlexLexer
  243. \#include <FlexLexer.h>
  244. #f
  245. #Wrap on
  246.  
  247. if, for example, you used {fEmphasis}%option prefix="xx"{f} for one of
  248. your scanners and {fEmphasis}%option prefix="zz"{f} for the other.
  249.  
  250. IMPORTANT: the present form of the scanning class is
  251. {fEmphasis}experimental{f} and may change considerably between major
  252. releases.
  253.  
  254.